
#include <assert.h>
#include <gfx/idevice.h>
#include <gfx/levelofdetail.h>
#include <gfx/mesh.h>
#include <gfx/renderenvironment.h>
#include <gfx/gl20/mesh/instancedmesh.h>
#include <GL/glew.h>


ceInstancedMeshGL20::ceInstancedMeshGL20()
  : _lodSolver(0)
  , _mesh(0)
{
}


ceInstancedMeshGL20::~ceInstancedMeshGL20()
{
  CE_UNSET(_mesh);
}


void ceInstancedMeshGL20::Update(const ceRenderEnvironment& env, iDevice* device)
{

	if (_generator)
		{
			_generator->Generate (env, device, _instanceData, _instanceUse, _instanceCount);
		}
  else if (_lodSolver)
    {
			ceVector3f d = env.CameraLocation - _bbox.GetCenter();
			float l = d.Length();

      _instanceUse = _instanceCount - _lodSolver->Solve(_instanceCount, l, _bbox.GetMediumRadius());

			if (_instanceUse > _instanceCount)
				{
					_instanceUse = 0;
				}
	}
}

void ceInstancedMeshGL20::UpdateBoundingBox()
{
	return;
}

void ceInstancedMeshGL20::SetMesh(ceMesh *mesh)
{
  CE_SET(_mesh, mesh);
}

ceMesh* ceInstancedMeshGL20::GetMesh()
{
  return _mesh;
}

const ceMesh* ceInstancedMeshGL20::GetMesh() const
{
  return _mesh;
}


void ceInstancedMeshGL20::AddInstanceData (const ceInstancedData& data)
{
	_instanceData.push_back (data);
}

const ceInstancedData& ceInstancedMeshGL20::GetInstanceData (unsigned idx) const
{
	assert (idx < _instanceData.size ());
	return _instanceData[idx];
}

unsigned ceInstancedMeshGL20::GetNumberOfInstanceData () const
{
	return _instanceData.size ();
}
